
package hasthi.wsdm.capabilities;

import hasthi.common.HasthiException;
import hasthi.common.HasthiException.FaultCode;
import hasthi.common.constants.WSDMConstants;
import hasthi.common.constants.WSDMConstants.SystemState;
import hasthi.wsdm.ManagedSystemHandle;

import javax.xml.namespace.QName;

import org.apache.xmlbeans.XmlObject;

import wsdm.mows.BusyStateDocument;
import wsdm.mows.CrashedStateDocument;
import wsdm.mows.IdleStateDocument;
import wsdm.mows.SaturatedStateDocument;
import wsdm.mows.StoppedStateDocument;
import wsdm.muws.StateTransitionDocument;
import wsdm.muws.StateTransitionType;
import edu.indiana.extreme.wsdm.ShutDownRequestDocument;
import edu.indiana.extreme.wsdm.ShutDownResponseDocument;

public class RunningSystemCapability extends AbstractCapability{
    private static QName CURRENT_OPERATIONAL_STATE = new QName(WSDMConstants.MUWS2_NAMESPACE,"CurrentOperationalState");
    private static QName LAST_OPERATIONAL_STATE_TRANSITION = new QName(WSDMConstants.MUWS2_NAMESPACE,"LastOperationalStateTransition");
    private static QName OPERATIONAL_STATUS = new QName(WSDMConstants.MUWS2_NAMESPACE,"OperationalStatus");
    
    public RunningSystemCapability() {
        super();
    }

    public Object getProperty(QName name) throws HasthiException {
        ManagedSystemHandle systemHandle = ownedResource.getSystemHandle();
        if(CURRENT_OPERATIONAL_STATE.equals(name)){
            SystemState state = systemHandle.getCurrentSystemState();
            switch(state){
                case BusyState:
                    BusyStateDocument busyStateDocument = BusyStateDocument.Factory.newInstance();
                    busyStateDocument.addNewBusyState().addNewUpState();
                    return busyStateDocument;
                case IdleState:
                    IdleStateDocument idleStateDocument = IdleStateDocument.Factory.newInstance();
                    idleStateDocument.addNewIdleState().addNewUpState();
                    return idleStateDocument;
                case SaturatedState:
                    SaturatedStateDocument saturatedStateDocument = SaturatedStateDocument.Factory.newInstance();
                    saturatedStateDocument.addNewSaturatedState().addNewDownState();
                    return saturatedStateDocument;
                    
                case StoppedState: 
                    StoppedStateDocument stateDocument =  StoppedStateDocument.Factory.newInstance();
                    stateDocument.addNewStoppedState().addNewDownState();
                    return stateDocument;
                case CrashedState:
                    CrashedStateDocument crashedStateDocument = CrashedStateDocument.Factory.newInstance();
                    crashedStateDocument.addNewCrashedState().addNewDownState();
                    return crashedStateDocument;
            }
        }else if(LAST_OPERATIONAL_STATE_TRANSITION.equals(name)){
          SystemState[] lastTransition = systemHandle.getLastStateTransition();
          StateTransitionDocument stateTransitionDocument = StateTransitionDocument.Factory.newInstance();
          StateTransitionType stateTransition = stateTransitionDocument.addNewStateTransition();
          stateTransition.addNewPreviousState().set(localStateType2XmlBeansStateType(lastTransition[0]));
          stateTransition.addNewEnteredState().set(localStateType2XmlBeansStateType(lastTransition[1]));
          return stateTransitionDocument;
        }
        
        if(OPERATIONAL_STATUS.equals(name)){
            SystemState state = systemHandle.getCurrentSystemState();
//            OperationalStatusDocument operationalStatus =  OperationalStatusDocument.Factory.newInstance();
//            switch(state){
//                case BusyState:case IdleState:
//                    operationalStatus.setOperationalStatus(OperationalStatus.AVAILABLE);
//                    break;
//                case SaturatedState:
//                    operationalStatus.setOperationalStatus(OperationalStatus.PARTIALLY_AVAILABLE);
//                    break;
//                default:
//                    operationalStatus.setOperationalStatus(OperationalStatus.UNAVAILABLE);
//            }
//            return operationalStatus;
            return state.toString();
        }
        throw new HasthiException("Unsupported property "+name + " requested from capability "+ this,FaultCode.InvaliedLocalArgumnet);
    }
    public void setProperty(QName name, Object value) throws HasthiException {
        throw new HasthiException("Unsupported property "+name + " set in capability "+ this,FaultCode.InvaliedLocalArgumnet);
    }
   
    private XmlObject localStateType2XmlBeansStateType(SystemState state){
        switch(state){
            case BusyState:
                BusyStateDocument busyStateDocument = BusyStateDocument.Factory.newInstance();
                busyStateDocument.addNewBusyState().addNewUpState();
                return busyStateDocument;
            case IdleState:
                IdleStateDocument idleStateDocument = IdleStateDocument.Factory.newInstance();
                idleStateDocument.addNewIdleState().addNewUpState();
                return idleStateDocument;
            case SaturatedState:
                SaturatedStateDocument saturatedStateDocument = SaturatedStateDocument.Factory.newInstance();
                saturatedStateDocument.addNewSaturatedState().addNewDownState();
                return saturatedStateDocument;
            case StoppedState: 
                StoppedStateDocument stateDocument =  StoppedStateDocument.Factory.newInstance();
                stateDocument.addNewStoppedState().addNewDownState();
                return stateDocument;
            default:
                CrashedStateDocument crashedStateDocument = CrashedStateDocument.Factory.newInstance();
                crashedStateDocument.addNewCrashedState().addNewDownState();
                return crashedStateDocument;
        }
    }
    
    public ShutDownResponseDocument shutDown(ShutDownRequestDocument document) throws HasthiException{
        ownedResource.getSystemHandle().shutDown();
        ownedResource.stop();
        System.out.println("ShutDown resource "+ownedResource.getName());
        ShutDownResponseDocument responseDocument = ShutDownResponseDocument.Factory.newInstance();
        responseDocument.addNewShutDownResponse();
        return responseDocument;
    }
}

